// import puppeteer from "puppeteer";
import { Server } from "../../store/server"
import { config } from "../../config"
import { IListConfig, IField, IMethod, IResAndReqFields } from "../../interface/type"
import request from "request"
import utilTool from "../../util/tool"

export class MethodAction {
  private page: any;
  // private serverStore: Server;
  private browser: any;
  private listConfig: IListConfig;
  private serverConfig: IMethod | null | undefined;
  private resAndReq: IResAndReqFields;
  private callBack: (res: IResAndReqFields)=>void;

  constructor(browser: any, serverStore: Server, listConfig: IListConfig) {
    // this.serverStore = serverStore
    this.browser = browser
    this.listConfig = listConfig
    this.serverConfig = (listConfig?.apiName ? serverStore.getMethod(listConfig?.apiName) : null)
    this.resAndReq = {
      request: [], // 请求参数
      response: [] // 请求结果
    }
    this.callBack = () => {}
  }

  public setResAndReq(resAndReq: IResAndReqFields) {
    this.resAndReq = resAndReq
  }

  public getResAndReq(): IResAndReqFields {
    return this.resAndReq
  }

  public setCallBack(callBack: (res: IResAndReqFields) => void) {
    this.callBack = callBack
  }

  public getCallBack(): (res: IResAndReqFields) => void {
    return this.callBack
  }

  // /**
  //  * 处理请求参数
  //  * @param response
  //  */
  // public async handleRequestHook(response: any) {
  //   if (response.url().indexOf("Request.htm") > 0) {
  //     const json: JSON = await response.json();
  //     console.log("json >> ", json)
  //   }
  // }

  // /**
  //  * 处理返回结果
  //  * @param response
  //  */
  // public async handleResponseHook(response: any) {
  //   if (response.url().indexOf("Response.htm") > 0) {
  //     const json: JSON = await response.json();
  //     console.log("json >> ", json)
  //   }
  // }

  /**
   * 获取数据
   * @param packageName
   */
  public getReqResult (packageName: string) {
    return new Promise( (resolve, reject) => request(`${config.href}/api/findstruct/${config.serverName}/1.0.0/${packageName}.htm`,
      (err, _, body) => {
        // console.log('err, response, body: ', err, response, body)
        if (err) {
          console.log('这里获取数据失败', err)
          reject(err);
        } else {
          if (typeof body === 'string') {
            resolve(JSON.parse(body));
          } else {
            resolve(body);
          }
        }
      })
    )
  }

  /**
   * 迭归的方式获取节点
   * @param res
   */
  public async findField(res: any): Promise<IField[]> {
    if (!res?.fields) {
      return []
    }
    const arr: IField[] = []
    for (const field of res?.fields) {
      if (field.name === 'pageRequest') {
        continue
      }
      const item: IField = {
        name: field.name, // 名称
        type: field?.dataType?.kind.toLowerCase(), // 类型
        isReq: !field?.dataType?.optional, // 是否必填
        description: utilTool.trimStr(field?.doc), // 描述
        isEnum: field?.dataType?.kind === "ENUM", // 是否是枚举
        EnumOptionName: field?.dataType?.kind === "ENUM" ? utilTool.getLastNameFromPackage(field?.dataType?.qualifiedName) : '', // 枚举的名称
      }
      if (field?.dataType?.kind === 'STRUCT') {
        const result = await this.getReqResult(field?.dataType?.qualifiedName)
        item.children = await this.findField(result)
      } else if (field?.dataType?.kind === 'LIST' && field?.dataType?.valueType?.kind === 'STRUCT') {
        console.log('进来一了')
        const result = await this.getReqResult(field?.dataType?.valueType?.qualifiedName)
        item.children = await this.findField(result)
      }
      arr.push(item)
    }
    return arr
  }

  /**
   * 处理请求参数
   * @param res
   */
  public async handleRequest(res: any): Promise<IField[]> {
    const field = res.fields[0]
    if (field?.dataType?.kind === 'VOID') {
      return []
    }
    const result = await this.getReqResult(field?.dataType?.qualifiedName)
    const arr: IField[] | undefined = await this.findField(result)
    console.log('-------request-----arr-----------')
    console.log(arr)
    return arr
  }

  /**
   * 处理请求结果
   * @param res
   */
  public async handleResponse(res: any): Promise<IField[]> {
    const field = res.fields[0]
    if (field?.dataType?.kind === 'VOID') {
      return []
    }
    const result = await this.getReqResult(field?.dataType?.qualifiedName)
    const arr: IField[] | undefined = await this.findField(result)
    console.log('----response--------arr-----------')
    console.log(arr)
    return arr
  }

  public async handleMethodHook(response: any) {
    if (this.serverConfig?.name && response.url().indexOf(`/${this.serverConfig?.name}.htm`) > 0 && response.url().indexOf(`findmethod`) > 0) {
      const json: {
        request: any,
        response: any
      } = await response.json();
      const req = await this.handleRequest(json?.request)
      const resp = await this.handleResponse(json?.response)
      console.log("req >> ", JSON.stringify(req))
      console.log("resp >> ", JSON.stringify(resp))
      const callBack = this.getCallBack()
      callBack({
        request: req,
        response: resp
      })
    }
  }

  public async startPageListen(): Promise<void> {
    console.log("开始页面监听");
    this.page.on("response", async (response: any) => {
      await this.handleMethodHook(response)
      // await this.handleRequestHook(response)
      // await this.handleResponseHook(response)
    })
  }

  // public async getServerList(): Promise<any> {
  //   // 通过 page.evaluate 在浏览器里执行
  //   await this.page.evaluate(() => {
  //     console.log("在浏览器里执行");
  //     // 获取请求参数
  //     document.querySelectorAll('.bs-docs-content .table-bordered')[1]?.querySelector('a')?.click()

  //     // 获取结果
  //     setTimeout(() => {
  //       document.querySelectorAll('.bs-docs-content .table-bordered')[2]?.querySelector('a')?.click()
  //     }, 400);
  //   })
  // }

  public async init(callBack: (res: IResAndReqFields) => void) {
    console.log('进来了－－>', this.listConfig?.apiName)
    const link = this.serverConfig?.link
    if (!this.listConfig?.apiName || !link) return
    console.log('准备打开链接: ', link)
    this.setCallBack(callBack)
    // 获取地址为‘http://woleigequ.net/’的Page对象
    // http://sandbox7-openapi.today36524.cn/api/method/PromotionOfGoodsService/1.0.0/listGoodsExtraInfoByImport.htm
    // const target = await this.browser.waitForTarget((t: any) => t.url() === `${config.href}${link}`)
    // await target.page();
    this.page = await this.browser.newPage();
    this.page.setJavaScriptEnabled(true)
    await this.startPageListen();
    await this.page.goto(`${config.href}${link}`);
  }

}